package one;

import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Task类
 *
 * @author yangchuan
 * @version 1.0 create at 2021/11/25
 */
public class Task {

    private String name;

    private List<Task> nextTask;

    private List<Task> prevTask;

    private static Map<String, Task> taskMap = new HashMap<>();

    public Task(String name, Task nextTask, Task prevTask) {
        this.name = name;
        this.nextTask = new LinkedList<>();
        this.nextTask.add(nextTask);
        this.prevTask = new LinkedList<>();
        this.prevTask.add(prevTask);
    }

    public Task() {

    }

    public Task(String name) {
        this.name = name;
        this.prevTask = new LinkedList<>();
        this.nextTask = new LinkedList<>();
    }

    private void setNextTask(Task t) {
        this.nextTask.add(t);
        t.prevTask.add(this);
    }


    static {

        Task H = new Task("H");
        Task C = new Task("C");
        Task A = new Task("A");
        Task D = new Task("D");
        Task F = new Task("F");
        Task B = new Task("B");
        Task G = new Task("G");
        Task E = new Task("E");

        H.setNextTask(C);
        C.setNextTask(A);
        A.setNextTask(D);
        D.setNextTask(F);
        B.setNextTask(G);
        B.setNextTask(E);
        G.setNextTask(A);
        G.setNextTask(E);
        E.setNextTask(F);

        taskMap.put("H", H);
        taskMap.put("B", B);
        taskMap.put("C", C);
        taskMap.put("G", G);
        taskMap.put("A", A);
        taskMap.put("E", E);
        taskMap.put("D", D);
        taskMap.put("F", F);
    }

    private static Task getTask(String name) {
        return taskMap.get(name);
    }

    public static String execute(String str) {
        //解析
        List<String> tasks = handleStr(str);

        StringBuilder res = new StringBuilder();

        Map<String, Integer> map = new HashMap<>();

        Queue<String> taskQueue = new LinkedBlockingQueue<>();

        tasks.forEach(e -> {
            map.put(e, 0);
            taskQueue.add(e);
        });

        while (!taskQueue.isEmpty()) {
            String name = taskQueue.poll();
            Task t = getTask(name);
            if (t.prevTask.size() == 0) {
                map.put(t.name, 1);
                res.append("Task " + name + ",");
            } else {
                boolean canExecute = true;
                for (Task prevT : t.prevTask) {
                    if (map.get(prevT.name).equals(0)) {
                        //重回队列
                        taskQueue.add(name);
                        canExecute = false;
                        break;
                    }
                }
                if (canExecute) {
                    map.put(t.name, 1);
                    res.append("Task " + name + ",");
                }
            }
        }

        return res.toString();

    }

    private static List<String> handleStr(String str) {
        List<String> res = new LinkedList<>();
        String[] split = str.split(",");
        for (String s : split) {
            res.add(s.substring(5));
        }
        return res;
    }

    public static void main(String[] args) {

        String execute = Task.execute("Task A,Task B,Task C,Task D,Task E,Task F,Task G,Task H");
        System.out.println(execute);

    }
}
